//
//  SeekoHTMLParser.m
//  MokoAPP
//
//  Created by 현식 강 on 11. 8. 27..
//  Copyright 2011 아이온. All rights reserved.
//

#import "SeekoHTMLParser.h"
#import "HTMLParser.h"
#import "MokoAppDelegate.h"
#import "HTMLParser.h"
#import "MenuVO.h"
#import "BoardListVO.h"
#import "ArticleAndCommentVO.h"
#import "CommentVO.h"
#import "MemoListVO.h"

@implementation SeekoHTMLParser
-(NSArray*)getMenu {
    NSMutableArray* returnArr = [[[NSMutableArray alloc] init] autorelease];
    HTMLParser* parser = [[HTMLParser alloc] initWithData:[responseString dataUsingEncoding:NSUTF8StringEncoding] error:nil];
    
    HTMLNode* body = [parser body];
    NSArray* left_depth1 = [body findChildrenWithAttribute:@"class" matchingName:@"menu_depth" allowPartial:YES];
    NSArray* left_depth2 = [body findChildrenWithAttribute:@"class" matchingName:@"left_depth" allowPartial:YES];
    NSMutableArray* left_depth1_txt = [[NSMutableArray alloc] init];
    for( int i = 0, l = [left_depth1 count]; i < l; i++ ) {
        HTMLNode* node = [[left_depth1 objectAtIndex:i] findChildTag:@"img"];
        [left_depth1_txt addObject:[node getAttributeNamed:@"title"]];
    }
    
    
    
    NSMutableArray* left2depth_text = [[NSMutableArray alloc] init];
    for( int i = 0, l = [left_depth2 count]; i < l; i++ ) {
        HTMLNode* node = [left_depth2 objectAtIndex:i];
        [left2depth_text addObject:[node allContents]];
    }
    // 1뎁스 메뉴만큼 루프를 돌며 2뎁스 메뉴들을 1뎁스의 메뉴별로 추가한다.
    for( int i = 0, l = [left_depth1 count]; i < l; i++ ) {
        MenuVO* menuVO = [[MenuVO alloc] init];
        menuVO.title = [left_depth1_txt objectAtIndex:i];
        menuVO.link = [[left_depth1 objectAtIndex:i] getAttributeNamed:@"href"];
        NSMutableArray* childArr = [[NSMutableArray alloc] init];
        menuVO.childVOArr = childArr;
        [childArr release];
        for( int j = 0, k = [left_depth2 count]; j < k; j++ ) {
            HTMLNode* element = [left_depth2 objectAtIndex:j];
            // 뎁스 구분자는 클래스 어트리뷰트로 하며 left_depthn 형식으로 끝의 n이 1뎁스 인지 2뎁스인지 구분을 시킨다.
            NSString* class = [element getAttributeNamed:@"class"];
            int left_depth_index = [class indexOf:@"left_depth"];
            if( left_depth_index != -1 ) {
                int idx = left_depth_index + [@"left_depth" length];
                NSString* idxstr = [class substringWithRange:NSMakeRange(idx,1)];
                idx = [idxstr intValue];
                // 같은 뎁스일때만 배열에 추가한다.
                if( idx-1 == i ) {
                    MenuVO* childMenuVO = [[MenuVO alloc] init];
                    childMenuVO.title = [element allContents];
                    childMenuVO.link = [element getAttributeNamed:@"href"];
                    [menuVO.childVOArr addObject:childMenuVO];
                    [childMenuVO release];
                }
            }
        }
        [returnArr addObject:menuVO];
        [menuVO release];
    }
    [left2depth_text release];
    [left_depth1_txt release];
    [parser release];
    return returnArr;
}
-(BoardListAllVO*)getArticleList {
    GET_APPDELEGATE;
    BoardListAllVO* allVO = nil;
    HTMLParser* parser = [[HTMLParser alloc] initWithData:[responseString dataUsingEncoding:NSUTF8StringEncoding] error:nil];
    @try {
        allVO = [[[BoardListAllVO alloc] init] autorelease];
        allVO.boardListVOArr = [[[NSMutableArray alloc] init] autorelease];
        HTMLNode* body = [parser body];
        
        int articleCount = 0;
        NSArray* links = [body findChildrenWithAttribute:@"class" matchingName:@"article_subject" allowPartial:YES];
        NSArray* dates = [body findChildrenWithAttribute:@"class" matchingName:@"article_date" allowPartial:YES];
        //NSArray* nameImage = nil;
        //NSArray* nameText = [parser search:delegate.xPathVO.nameText];
        NSArray* count = [body findChildrenWithAttribute:@"class" matchingName:@"article_count" allowPartial:YES];
        NSArray* noticeCount = [body findChildrenWithAttribute:@"class" matchingName:@"notice_list" allowPartial:YES];
        NSArray* page = [body findChildrenWithAttribute:@"style" matchingName:@"font-size:8pt" allowPartial:YES];
        HTMLNode* pageNode = nil;
        for( int i = 0, l = [page count]; i < l; i++ ) {
            HTMLNode* temp = [page objectAtIndex:i];
            HTMLNode* node = [temp findChildTag:@"b"];
            if( node != nil ) {
                pageNode = node;
                break;
            }
        }
        if( pageNode != nil ) {
            allVO.page = [[pageNode allContents] intValue];
        } 
        else
            allVO.page = 0;
        articleCount = [dates count];
        
        // 로그인 체크
        NSArray* login = [body findChildrenWithAttribute:@"class" matchingName:@"logged" allowPartial:YES];
        if( [login count] > 0 )
            delegate.httpClient.isLogin = YES;
        else
            delegate.httpClient.isLogin = NO;
        // 목록의 ID를 가져온다.
        NSArray* scriptArr = [body findChildTags:@"script"];
        NSString* scriptStr = nil;
        for( int i = 0, l = [scriptArr count]; i < l; i++ ) {
            NSString* scriptContents = [[scriptArr objectAtIndex:i] allContents];
            if( [scriptContents rangeOfString:@"print_ZBlayer"].location != NSNotFound ) {
                scriptStr = [[[[scriptContents stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] stringByReplacingOccurrencesOfString:@"print_ZBlayer(" withString:@""] stringByReplacingOccurrencesOfString:@")" withString:@""] stringByReplacingOccurrencesOfString:@"'" withString:@""];
                break;
            }
        }
        HTMLNode* memoSent = [body findChildWithAttribute:@"src" matchingName:@"i_memo_on.gif" allowPartial:YES];
        if( memoSent != nil ) {
            [[NSNotificationCenter defaultCenter] postNotificationName:MEMO_NOTIFICATION object:nil];
        }
        NSArray* layers = [scriptStr componentsSeparatedByString:@";"];
        /*
         if( articleCount > 0 ) {
         NSArray* tokens = [[layers objectAtIndex:0] componentsSeparatedByString:@","];
         
         if( [[tokens objectAtIndex:5] length] == 0 ) {
         // 스폰서 게시판의 경우 이름이 이미지임
         nameImage = [parser search:delegate.xPathVO.nameImage];
         }
         }
         */
        NSArray* articleNames = [body findChildrenWithAttribute:@"class" matchingName:@"article_name" allowPartial:YES];
        BOOL nameAndArticleCountEqual = NO;
        if( [articleNames objectAtIndex:0] != nil )
            nameAndArticleCountEqual = ( [[[articleNames objectAtIndex:0] allContents] length] > 0 ) ? YES : NO;
        for( int i = 0; i < articleCount; i++ ) {
            BoardListVO* vo = [[BoardListVO alloc] init];
            if( i < [noticeCount count] )
                vo.isNoticeArticle = YES;
            else
                vo.isNoticeArticle = NO;
            
            if( !([delegate.configVO.showNotice boolValue] == NO && vo.isNoticeArticle == YES) ) {
                vo.date = [[dates objectAtIndex:i] allContents];
                
                // 공백 제거, [] 제거 stringByReplacingOccurrencesOfString:@"[" withString:@""] stringByReplacingOccurrencesOfString:@"]" withString:@""]
                HTMLNode* titleNode = [links objectAtIndex:i];
                NSString* title = [titleNode allContents];
                vo.commentCount = [[[[[titleNode findChildWithAttribute:@"class" matchingName:@"comment_count" allowPartial:YES] allContents] stringByReplacingOccurrencesOfString:@"[" withString:@""] stringByReplacingOccurrencesOfString:@"]" withString:@""] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
                if( [vo.commentCount length] == 0 ) {
                    vo.commentCount = @"0";
                }
                // 댓글이 0보다 크면 제목에서 댓글을 제거
                if( [vo.commentCount intValue] > 0 ) {
                    int index = [title lastIndexOf:@"["];
                    if( index != NSNotFound )
                        title = [title substringWithRange:NSMakeRange(0, index)];
                }
                vo.title = [title stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
                if( [links count] == articleCount ) {
                    vo.link = [[titleNode findChildTag:@"a"] getAttributeNamed:@"href"];
                }
                // 글쓴 사람 ID값 구하기
                NSArray* scriptTokens = [[layers objectAtIndex:i] componentsSeparatedByString:@","];
                vo.userId = [scriptTokens objectAtIndex:3];
                NSString* nameText = [[scriptTokens objectAtIndex:5] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
                if( nameAndArticleCountEqual == NO ) 
                    nameText = [[scriptTokens objectAtIndex:5] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
                else 
                    nameText = [[articleNames objectAtIndex:i] allContents];
                if( [nameText length] != 0 ) {
                    // 기존 이름 가져오는 방식, 현재는 속도를 위해 스크립트에서 가져오는 방식으로 변경 이 방식은 스폰서 게시판의 이미지도 아이디로 표현해줌
                    //                NSMutableString* str = [[NSMutableString alloc] init];
                    //                [TFHppleElement allChildrenTextConcatenation:[nameText objectAtIndex:i] result:str];
                    //                vo.nameText = [str stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
                    //                [str release];
                    vo.nameText = [nameText stringByReplacingPercentEscapesUsingEncoding:EUC_KR];
                }
                vo.count = [[count objectAtIndex:i] allContents];
                [allVO.boardListVOArr addObject:vo];
            }
            [vo release];
        }
        // 글 쓰기 권한 체크
        NSArray* write = [body findChildrenWithAttribute:@"class" matchingName:@"view_write" allowPartial:YES];
        if( write != nil ) {
            allVO.writable = YES;
        }
        else
            allVO.writable = NO;
    }
    @catch (NSException* exception) {
        allVO = nil;
    } 
    @finally {
        [parser release];
    }
    return allVO;
}
-(void)memberInfo {
    HTMLParser* parser = [[HTMLParser alloc] initWithData:[responseString dataUsingEncoding:NSUTF8StringEncoding] error:nil];
    NSAutoreleasePool* myPool = [[NSAutoreleasePool alloc] init];
    HTMLNode* body = [parser body];
    NSArray* infoArr = [[[body allContents] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] componentsSeparatedByString:@"\n"];
    NSMutableString* infoStr = [[[NSMutableString alloc] init] autorelease];
    for( int i = 0, l = [infoArr count]; i < l; i++ ) {
        NSString* str = [[infoArr objectAtIndex:i] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
        if( [str rangeOfString:@"alert("].location != NSNotFound ) {
            [infoStr appendString:@"정보가 공개 되어 있지 않습니다."];
            break;
        }
        else if( [str length] > 0 )
            [infoStr appendFormat:@"%@\n",str];
    }
    UIAlertView* alert = [[[UIAlertView alloc] initWithTitle:@"회원정보" message:infoStr delegate:nil cancelButtonTitle:nil otherButtonTitles:@"확인", nil] autorelease];
    [alert show];
    [myPool release];
    [parser release];
}
-(ArticleAndCommentVO*)getArticleAndComment {
    ArticleAndCommentVO* vo = [[[ArticleAndCommentVO alloc] init] autorelease];
    HTMLParser* parser = [[HTMLParser alloc] initWithData:[responseString dataUsingEncoding:NSUTF8StringEncoding] error:nil];
    HTMLNode* body = [parser body];
    
    HTMLNode* viewContent = [body findChildWithAttribute:@"class" matchingName:@"view_content" allowPartial:YES];
    // td 내용(본문)
    HTMLNode* td = [viewContent findChildTag:@"td"];
    // 이미지 내용
    NSArray* imgs = [viewContent findChildrenWithAttribute:@"src" matchingName:@"data/" allowPartial:YES];
    // 링크 내용
    NSArray* links = [body findChildrenWithAttribute:@"class" matchingName:@"view_link" allowPartial:YES];
    NSMutableArray* finalLinks = [[NSMutableArray alloc] init];
    for( int i = 0, l = [links count]; i < l; i++ ) {
        HTMLNode* node = [[links objectAtIndex:i] findChildTag:@"a"];
        if( node != nil )
            [finalLinks addObject:node];
        else
            [finalLinks addObject:[[links objectAtIndex:i] allContents]];
    }
    
    NSString* viewRawContent = @"";
    // 뷰 이미지, 링크들
    NSString* articleImgs = @"";
    NSString* articleLinks = @"";
    if( td != nil ) {
        viewRawContent = [td rawContents];
    }
    
    for( int i = 0, l = [finalLinks count]; i < l; i++ ) {
        id object = [finalLinks objectAtIndex:i];
        if( [object isKindOfClass:[HTMLNode class]] )
            articleLinks = [NSString stringWithFormat:@"%@<br>%@",[object rawContents], articleLinks];
        else
            articleLinks = [NSString stringWithFormat:@"%@<br>%@",object, articleLinks];
    }
    [finalLinks release];
    // 이상하게 이미지가 거꾸로 나옴... 그래서 반대로 돌림
    for( int i = [imgs count]-1; i >= 0; i-- ) {
        articleImgs = [NSString stringWithFormat:@"%@<br>%@",[[imgs objectAtIndex:i] rawContents], articleImgs];
    }
    vo.articleImgs = articleImgs;
    vo.articleLinks = articleLinks;
    vo.viewRawContent = viewRawContent;
    
    NSArray* commentDate = [body findChildrenWithAttribute:@"class" matchingName:@"commentdate" allowPartial:YES];
    
    
    HTMLNode* modify = [body findChildWithAttribute:@"class" matchingName:@"view_modify" allowPartial:YES];
    HTMLNode* delete = [body findChildWithAttribute:@"class" matchingName:@"view_delete" allowPartial:YES];
    if( modify != nil ) {
        vo.editable = YES;
    }
    if( delete != nil ) {
        vo.deletable = YES;
    }
    
    HTMLNode* memoSent = [body findChildWithAttribute:@"src" matchingName:@"i_memo_on.gif" allowPartial:YES];
    if( memoSent != nil ) {
        [[NSNotificationCenter defaultCenter] postNotificationName:MEMO_NOTIFICATION object:nil];
    }
    NSArray* title = [body findChildrenWithAttribute:@"class" matchingName:@"view_subject" allowPartial:YES];
    if( [title count] != 0 ) {
        
        NSArray* userLevel = [body findChildrenWithAttribute:@"class" matchingName:@"view_warning" allowPartial:YES];
        NSString* titleStr = [[title objectAtIndex:0] allContents];
        vo.title = titleStr;
        // 타이틀 세팅
        // 유저이름
        if( [userLevel count] != 0 ) {
            NSString* u_level = [[userLevel objectAtIndex:0] allContents];
            vo.userLevelStr = u_level;
        }
        
        @try {
            
            NSArray* commentContent = [body findChildrenWithAttribute:@"class" matchingName:@"commentcontent" allowPartial:YES];
            NSArray* nobr = [body findChildTags:@"nobr"];
            
            NSArray* scriptArr = [body findChildTags:@"script"];
            NSString* scriptStr = nil;
            for( int i = 0, l = [scriptArr count]; i < l; i++ ) {
                NSString* scriptContents = [[scriptArr objectAtIndex:i] allContents];
                if( [scriptContents rangeOfString:@"print_ZBlayer"].location != NSNotFound ) {
                    scriptStr = [[[[scriptContents stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] stringByReplacingOccurrencesOfString:@"print_ZBlayer(" withString:@""] stringByReplacingOccurrencesOfString:@")" withString:@""] stringByReplacingOccurrencesOfString:@"'" withString:@""];
                    break;
                }
            }
            NSArray* layers = [scriptStr componentsSeparatedByString:@";"];
            // 글쓴 사람 ID값 구하기
            vo.userId = [[[[layers objectAtIndex:0] componentsSeparatedByString:@","] objectAtIndex:3] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
            vo.commentArr = [[[NSMutableArray alloc] initWithCapacity:[commentContent count]] autorelease];
            for( int i = 1, l = [commentContent count]+1; i < l; i++ ) {
                CommentVO* cvo = [[CommentVO alloc] init];
                
                NSArray* scriptTokens = [[layers objectAtIndex:i] componentsSeparatedByString:@","];
                NSString* commentUserId = [scriptTokens objectAtIndex:3];
                cvo.commentID = [commentUserId stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
                [vo.commentArr addObject:cvo];
                [cvo release];
            }
            
            
            for( int i = 0, l = [commentContent count]; i < l; i++ ) {
                NSString* name = [[[nobr objectAtIndex:i] findChildTag:@"span"] allContents];
                NSString* _content = [[[[[commentContent objectAtIndex:i] rawContents] stringByReplacingOccurrencesOfString:@"<br>" withString:@"@br@"] stringByConvertingHTMLToPlainText] stringByReplacingOccurrencesOfString:@"@br@" withString:@"\n"];
                NSString* level = [[[[nobr objectAtIndex:i] nextSibling] nextSibling] allContents];
                HTMLNode* dateNode = [commentDate objectAtIndex:i];
                NSString* date = [[[dateNode rawContents] stringByReplacingOccurrencesOfString:@"<br>" withString:@" "] stringByConvertingHTMLToPlainText];
                HTMLNode* deletable = [[dateNode parent] findChildTag:@"a"];
                NSString* deletableId = @"";
                if( deletable != nil ) {
                    deletableId = [[[deletable getAttributeNamed:@"href"] componentsSeparatedByString:@"c_no="] objectAtIndex:1];
                }
                CommentVO* cvo = [vo.commentArr objectAtIndex:i];
                cvo.date = date;
                cvo.name = name;
                cvo.content = _content;
                cvo.level = level;
                cvo.deletableCommentID = deletableId;
            }
        }
        @catch (NSException *exception) {
            NSLog(@"%@\n%@", [exception name], [exception reason]);
            UIAlertView* av = [[UIAlertView alloc] initWithTitle:@"에러" message:@"댓글 파싱중 에러가 발생하였습니다." delegate:nil cancelButtonTitle:nil otherButtonTitles:@"확인", nil];
            [av show];
            [av release];
            
        }
    }
    [parser release];
    return vo;
}
-(NSString*)getError {
    HTMLParser* parser = [[HTMLParser alloc] initWithData:[responseString dataUsingEncoding:NSUTF8StringEncoding] error:nil];
    HTMLNode* body = [parser body];
    NSString* result = @"";
    HTMLNode* error = [body findChildWithAttribute:@"class" matchingName:@"yeinsub" allowPartial:YES];
    
    if( error != nil ) {
        HTMLNode* errorMessageNode = [[[error parent] parent] parent];
        result = [[[[[errorMessageNode allContents] stringByReplacingOccurrencesOfString:@"ERROR" withString:@""] stringByReplacingOccurrencesOfString:@"Back" withString:@""] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] stringByReplacingOccurrencesOfString:@"Move" withString:@""];
    }
    
    [parser release];
    return result;
}
-(MemoListAllVO*)getMemoList {
    MemoListAllVO* vo = [[[MemoListAllVO alloc] init] autorelease];
    vo.memoVOArr = [[[NSMutableArray alloc] init] autorelease];
    HTMLParser* parser = [[HTMLParser alloc] initWithData:[responseString dataUsingEncoding:NSUTF8StringEncoding] error:nil];
    HTMLNode* body = [parser body];
    NSArray* b = [body findChildTags:@"b"];
    NSArray* date = [body findChildTags:@"span"];
    vo.page = [[[b objectAtIndex:2] allContents] intValue];
    NSArray* atag = [body findChildrenWithAttribute:@"href" matchingName:@"exec=view" allowPartial:YES];
    vo.newMessageCnt = [[[b objectAtIndex:1] contents] intValue];
    for( int i = 0, l = [atag count]; i < l; i++ ) {
        MemoListVO* mvo = [[MemoListVO alloc] init];
        HTMLNode* node = [atag objectAtIndex:i];
        HTMLNode* name = [node parent];
        name = [[name nextSibling] nextSibling];
        NSString* text = [node allContents];
        NSString* param = [node getAttributeNamed:@"href"];
        NSDictionary* dic1 = [param parseQueryString];
        NSString* no = [dic1 objectForKey:@"no"];
        mvo.date = [[date objectAtIndex:i] getAttributeNamed:@"title"];
        mvo.title = text;
        mvo.link = param;
        mvo.no = no;
        mvo.name = [name allContents];
        [vo.memoVOArr addObject:mvo];
        [mvo release];
    }
    [parser release];
    return vo;
}
-(BOOL)getMemoWriteResult {
    return [responseString rangeOfString:@"쪽지를 보냈습니다"].location != NSNotFound;
}
-(MemoArticleVO*)getMemoArticle {
    MemoArticleVO* vo = [[[MemoArticleVO alloc] init] autorelease];
    if( [responseString rangeOfString:@"alert(\"로그인된"].location == NSNotFound ) {
        vo.login = YES;
        HTMLParser* parser = [[HTMLParser alloc] initWithData:[responseString dataUsingEncoding:NSUTF8StringEncoding] error:nil];
        HTMLNode* body = [parser body];
        NSArray* memo_memo = [body findChildrenWithAttribute:@"src" matchingName:@"memo_memo.gif" allowPartial:YES];
        HTMLNode* replynode = [body findChildWithAttribute:@"src" matchingName:@"memo_reply.gif" allowPartial:YES];
        
        vo.replyable = ( replynode != nil ) ? YES : NO;
        if( vo.replyable == YES ) {
            NSArray* member = [[[replynode parent] getAttributeNamed:@"href"] componentsSeparatedByString:@"member_no="];
            vo.userId = [[[member objectAtIndex:1] componentsSeparatedByString:@"'"] objectAtIndex:0];
        }
        if( [memo_memo count] == 1 ) {
            HTMLNode* memo = [memo_memo objectAtIndex:0];
            memo = [memo parent];
            memo = [[memo nextSibling] nextSibling];
            NSString* memoStr = [NSString stringWithFormat:@"<html><body>%@</body></html>", [[memo rawContents] stringByReplacingOccurrencesOfString:@"<br>" withString:@"\n"]];
            HTMLParser* tempParser = [[HTMLParser alloc] initWithString:memoStr error:nil];
            HTMLNode* tempBody = [tempParser body];
            vo.content = [[tempBody allContents] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
            [tempParser release];
        }
        [parser release];
    } else {
        vo.login = NO;
    }
    
    return vo;
}
+(SeekoHTMLParser*)sharedSeekoHTMLParser {
    static SeekoHTMLParser* instance = nil;
    if( instance == nil ) {
        @synchronized(self) {
            if( instance == nil )
                instance = [[SeekoHTMLParser alloc] init];
        }
    }
    return instance;
}
-(void)dealloc {
    [super dealloc];
}
@end
